package com.enjoy.cap7_bean_life_cycle.bean2;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 参考：https://mp.weixin.qq.com/s/jdYAceB8fUqyww-9quoYpg
 * @author huangweiyue
 * 1.Bean容器在配置文件中找到Person Bean的定义，这个可以说是妈妈怀上了。
 * 2.Bean容器使用Java 反射API创建Bean的实例，孩子出生了。
 * 3.Person声明了属性no、name，它们会被设置，相当于注册身份证号和姓名。如果属性本身是Bean，则将对其进行解析和设置。
 * 4.Person类实现了BeanNameAware接口，通过传递Bean的名称来调用setBeanName()方法，相当于起个学名。
 * 5.Person类实现了BeanFactoryAware接口，通过传递BeanFactory对象的实例来调用setBeanFactory()方法，就像是选了一个学校。
 * 6.PersonBean实现了BeanPostProcessor接口，在初始化之前调用用postProcessBeforeInitialization()方法，相当于入学报名。
 * 7.PersonBean类实现了InitializingBean接口，在设置了配置文件中定义的所有Bean属性后，调用afterPropertiesSet()方法，就像是入学登记。
 * 8.配置文件中的Bean定义包含init-method属性，该属性的值将解析为Person类中的方法名称，初始化的时候会调用这个方法，成长不是走个流程，还需要自己不断努力。
 * 9.Bean Factory对象如果附加了Bean 后置处理器，就会调用postProcessAfterInitialization()方法，毕业了，总得拿个证。
 * 10.Person类实现了DisposableBean接口，则当Application不再需要Bean引用时，将调用destroy()方法，简单说，就是人挂了。
 * 11.配置文件中的Person Bean定义包含destroy-method属性，所以会调用Person类中的相应方法定义，相当于选好地儿，埋了
 */
//AbstractApplicationContext类里的refresh方法，这个方法是ApplicationContext容器初始化的关键点,
// 最终经过一阵七拐八绕，到达了我们的目标——Bean创建的方法：doGetBean方法，在这个方法里可以看到Bean的实例化，赋值、初始化的过程，至于最终的销毁，可以看看ConfigurableApplicationContext#close()
public class TestBeanLifeCycle {

    public static void main(String[] args) {
        //spring-config.xml
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        PersonBean personBean = (PersonBean) context.getBean("personBean");
        personBean.work();
        context.destroy();
    }
}